package com.gmrz.uaf.servlet.v1.handler;

import com.gmrz.uaf.common.Constants;
import com.gmrz.uaf.common.GuiceUtil;
import com.gmrz.uaf.protocol.v1.json.UAFSchemaBuilder;
import com.gmrz.uaf.protocol.v1.processor.UAFAddUviProcessor;
import com.gmrz.uaf.protocol.v1.processor.UAFGetCertInfoProcessor;
import com.gmrz.uaf.protocol.v1.schema.AdditionUvi;
import com.gmrz.uaf.protocol.v1.schema.CertificateShowBean;
import com.gmrz.uaf.protocol.v1.schema.DeviceDetails;
import com.gmrz.uaf.server.ServerConfig;
import com.gmrz.uaf.server.ServerContext;
import com.gmrz.uaf.servlet.v1.request.AddUviContext;
import com.gmrz.uaf.servlet.v1.request.GetCertInfoContext;
import com.gmrz.uaf.servlet.v1.request.ReceiveReqPayload;
import com.gmrz.uaf.servlet.v1.response.FidoRespPayload;
import com.gmrz.uaf.servlet.v1.validation.PayloadValidationException;
import com.gmrz.uaf.servlet.v1.validation.RestValidator;
import com.gmrz.util.Convert;
import com.gmrz.util.CryUtil;
import com.gmrz.util.Strings;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.lang.reflect.Type;
import java.util.List;

/**
 *
 */
public class UAFGetCertInfoHandler extends UAFBaseHandler {

    private static final Logger LOG = LogManager.getLogger(UAFGetCertInfoHandler.class);


    /**
     * @param request
     */
    public String getCertInfo(String request) {

        LOG.info("[/req/getcertinfo][begin]");
        ServerContext.getServerContext().getFidoLog().setRequest(request);
        FidoRespPayload<List<CertificateShowBean>> respPayload = new FidoRespPayload<List<CertificateShowBean>>();
        String response = null;
        try {


            Gson gson = UAFSchemaBuilder.getGson();
            Type reqType = new TypeToken<ReceiveReqPayload<GetCertInfoContext>>() {
            }.getType();

            ReceiveReqPayload<GetCertInfoContext> reqPayload = gson.fromJson(request, reqType);
            // 兼容 旧接口的deviceID
            if (Strings.isNullOrEmpty(reqPayload.getContext().getDeviceID()) && null != reqPayload.getContext().getDevices()) {
                reqPayload.getContext().setDeviceID(reqPayload.getContext().getDevices().getDeviceID());
            }
            if (Strings.isNotBlank(reqPayload.getContext().getDeviceID()) && null == reqPayload.getContext().getDevices()) {
                DeviceDetails deviceDetails = new DeviceDetails();
                deviceDetails.setDeviceID(reqPayload.getContext().getDeviceID());
                reqPayload.getContext().setDevices(deviceDetails);
            }
            GetCertInfoContext getCertInfoContext = reqPayload.getContext();
            logRequest(request, reqPayload.getContext().getTransNo(), getCertInfoContext.getUserName(),
                    getCertInfoContext.getAppID(), null,null, Constants.Method.GET_CERT_INFO);
            validate(reqPayload);
            UAFGetCertInfoProcessor processor = GuiceUtil.getProcessorInjector().
                    getInstance(UAFGetCertInfoProcessor.class);

            String deviceID = null;
            if(null != getCertInfoContext.getDevices()) {
                deviceID = getCertInfoContext.getDevices().getDeviceID();
            }
            // hash 用户名
            String hashedUserName = generateHashedUserName(getCertInfoContext.getUserName(), getCertInfoContext.getRf1(), getCertInfoContext.getRf2());

            List<CertificateShowBean> certificateShowBeans = processor.getCertInfos(hashedUserName,deviceID,getCertInfoContext.getAppID());
            if(null == certificateShowBeans || certificateShowBeans.isEmpty()){
                int statusCode = Constants.StatusCode.INTERNAL_SERVER_ERROR.getCode();
                String description = "Server returned empty response.";
                respPayload.setStatusCode(statusCode);
                respPayload.setDescription(description);
                return gson.toJson(respPayload);
            }
            respPayload.setStatusCode(1200);
            respPayload.setDescription("OK");
            respPayload.setUafRequest(certificateShowBeans);
            return gson.toJson(respPayload);
        } catch (Exception ex) {
            LOG.error(ex);
            response = buildFidoRespFromException(respPayload, ex);
        }
        LOG.info("[/req/getcertinfo][end]");
        return response;
    }

    private void validate(ReceiveReqPayload<GetCertInfoContext> reqPayload)
            throws PayloadValidationException {
        if ((reqPayload == null) || (reqPayload.getContext() == null)) {
            throw new PayloadValidationException("context", RestValidator.VALIDATION_ERROR.EMPTY);
        }
        RestValidator.validate("transNo", reqPayload.getContext().getTransNo());
        RestValidator.validate("userName", reqPayload.getContext().getUserName());
        RestValidator.validate("rf1", reqPayload.getContext().getRf1());
        RestValidator.validate("rf2", reqPayload.getContext().getRf2());
        RestValidator.validate("appID", reqPayload.getContext().getAppID());
        RestValidator.validateDevices(reqPayload.getContext().getDevices());
    }
}


